#20250613 尤文杰
import tkinter as tk
import random

# 生成 10 个 0~99 的随机数
numbers = [random.randint(0, 99) for _ in range(10)]
selected_indices = []  # 记录选中的索引
selection_count = 0  # 记录总选择次数
swap_count = 0  # 记录有效交换次数

# 创建主窗口
root = tk.Tk()
root.title("冒泡排序探究游戏")
root.geometry("600x400")  # 窗口加宽 100px

# 数字标签（默认隐藏）
num_labels = [
    tk.Label(root, text="?", font=("Arial", 18, "bold"), width=2, height=1, relief="solid", bg="white")
    for _ in range(10)
]
# 配置列的权重，确保每列都均匀分配宽度
for i in range(10):
    root.grid_columnconfigure(i, weight=1, uniform="equal")

#for i, label in enumerate(num_labels):
#    label.grid(row=0, column=i, padx=3, pady=10, ipadx=10, ipady=10)  # 让每个方格均匀排列

# 将标签放置到网格中
for i, label in enumerate(num_labels):
    label.grid(row=0, column=i, padx=3, pady=10, ipadx=10, ipady=10, sticky="nsew")  # 让每个方格均匀排列

# 位置编号标签（字号加大）
pos_labels = [tk.Label(root, text=str(i), font=("Arial", 18, "bold")) for i in range(10)]
for i, label in enumerate(pos_labels):
    label.grid(row=1, column=i, pady=5)

# 显示用户选择状态
status_label = tk.Label(root, text="请选择两个数字（按 0-9）", font=("Arial", 18))
status_label.grid(row=2, columnspan=10, pady=10)

# 交换按钮（默认禁用，等用户选择 2 个数字后才启用）
swap_button = tk.Button(root, text="交换 (按 Y)", font=("Arial", 18), state="disabled")
swap_button.grid(row=3, column=2, pady=10, columnspan=3)

# 取消选择按钮
reset_button = tk.Button(root, text="取消选择 (按 N)", font=("Arial", 18), command=lambda: reset_selection())
reset_button.grid(row=3, column=6, pady=10, columnspan=3)

# 选择次数统计
selection_label = tk.Label(root, text="选择比较次数：0", font=("Arial", 18))
selection_label.grid(row=4, columnspan=10, pady=5)

# 交换次数统计
swap_label = tk.Label(root, text="有效交换次数：0", font=("Arial", 18))
swap_label.grid(row=5, columnspan=10, pady=5)

# 选择两个数字
def select_box(event):
    global selected_indices, selection_count
    key = event.char  # 获取按下的键

    # 确保按键是 0-9 之间的数字
    if key.isdigit():
        if len(selected_indices) != 2:
            index = int(key)
            if index in selected_indices:
                status_label.config(text=f"位置 {index} 已选！请选择其他位置。", fg="red")
                return
            
            selected_indices.append(index)
            selection_count += 1  # 增加选择次数
            selection_label.config(text=f"选择次数：{selection_count/2}")

            # 显示选中数字
            num_labels[index].config(text=str(numbers[index]), bg="lightblue")

            if len(selected_indices) == 2:
                i, j = selected_indices
                status_label.config(text=f"选中位置 {i} ({numbers[i]}) 和 {j} ({numbers[j]}), 按 Y 交换 / 按 N 取消")
                swap_button.config(state="normal", command=lambda: swap_numbers(i, j))  # 启用交换按钮
            else:
                status_label.config(text=f"已选择位置 {index}，请再选一个")

# 交换两个数
def swap_numbers(i, j):
    global selected_indices, swap_count
    if numbers[i] != numbers[j]:  # 只有不同的数才算有效交换
        numbers[i], numbers[j] = numbers[j], numbers[i]
        swap_count += 1
        swap_label.config(text=f"有效交换次数：{swap_count}")

    # 更新 UI
    num_labels[i].config(text="?", bg="white")  # 交换后隐藏
    num_labels[j].config(text="?", bg="white")

    selected_indices = []
    swap_button.config(state="disabled")  # 交换后禁用按钮
    status_label.config(text="交换完成，请继续选择")

    # 检查是否排序完成
    if numbers == sorted(numbers):
        status_label.config(text="🎉 排序成功！所有数字已按顺序排列 🎉", fg="green")
        for k in range(10):
            num_labels[k].config(text=str(numbers[k]), bg="lightgreen")  # 全部显示排序后的数字

# 取消选择
def reset_selection():
    global selected_indices
    for idx in selected_indices:
        num_labels[idx].config(text="?", bg="white")
    selected_indices = []
    swap_button.config(state="disabled")
    status_label.config(text="请选择两个数字（按 0-9）", fg="black")

# 绑定键盘事件
root.bind("<KeyPress>", select_box)
root.bind("<y>", lambda event: swap_numbers(*selected_indices) if len(selected_indices) == 2 else None)
root.bind("<n>", lambda event: reset_selection())

root.mainloop()
